; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -mtriple=arm -type-promotion -verify -disable-type-promotion=false -S %s -o - | FileCheck %s

define i32 @clear_structures(i8* nocapture readonly %fmt, [1 x i32] %ap.coerce, i8* %out, void (i32, i8*)* nocapture %write) {
; CHECK-LABEL: @clear_structures(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    br label [[WHILE_COND_OUTER:%.*]]
; CHECK:       while.cond.outer:
; CHECK-NEXT:    [[FMT_ADDR_0_PH:%.*]] = phi i8* [ [[FMT:%.*]], [[ENTRY:%.*]] ], [ [[FMT_ADDR_3:%.*]], [[WHILE_COND_OUTER_BACKEDGE:%.*]] ]
; CHECK-NEXT:    [[TMP0:%.*]] = load i8, i8* [[FMT_ADDR_0_PH]], align 1
; CHECK-NEXT:    br label [[WHILE_COND:%.*]]
; CHECK:       while.cond:
; CHECK-NEXT:    switch i8 [[TMP0]], label [[WHILE_COND]] [
; CHECK-NEXT:    i8 0, label [[WHILE_END48:%.*]]
; CHECK-NEXT:    i8 37, label [[WHILE_COND2:%.*]]
; CHECK-NEXT:    ]
; CHECK:       while.cond2:
; CHECK-NEXT:    [[FLAGS_0:%.*]] = phi i32 [ [[OR:%.*]], [[WHILE_COND2]] ], [ 0, [[WHILE_COND]] ]
; CHECK-NEXT:    [[FMT_ADDR_0_PN:%.*]] = phi i8* [ [[FMT_ADDR_1:%.*]], [[WHILE_COND2]] ], [ [[FMT_ADDR_0_PH]], [[WHILE_COND]] ]
; CHECK-NEXT:    [[FMT_ADDR_1]] = getelementptr inbounds i8, i8* [[FMT_ADDR_0_PN]], i32 1
; CHECK-NEXT:    [[TMP1:%.*]] = load i8, i8* [[FMT_ADDR_1]], align 1
; CHECK-NEXT:    [[SUB:%.*]] = add i8 [[TMP1]], -32
; CHECK-NEXT:    [[CONV6:%.*]] = zext i8 [[SUB]] to i32
; CHECK-NEXT:    [[SHL:%.*]] = shl i32 1, [[CONV6]]
; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SHL]], 75785
; CHECK-NEXT:    [[TOBOOL7:%.*]] = icmp eq i32 [[AND]], 0
; CHECK-NEXT:    [[OR]] = or i32 [[SHL]], [[FLAGS_0]]
; CHECK-NEXT:    br i1 [[TOBOOL7]], label [[WHILE_COND10_PREHEADER:%.*]], label [[WHILE_COND2]]
; CHECK:       while.cond10.preheader:
; CHECK-NEXT:    [[DOTOFF:%.*]] = add i8 [[TMP1]], -48
; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[DOTOFF]], 10
; CHECK-NEXT:    br i1 [[TMP2]], label [[WHILE_COND10:%.*]], label [[WHILE_END18_SPLIT:%.*]]
; CHECK:       while.cond10:
; CHECK-NEXT:    br label [[WHILE_COND10]]
; CHECK:       while.end18.split:
; CHECK-NEXT:    [[CMP20:%.*]] = icmp eq i8 [[TMP1]], 46
; CHECK-NEXT:    br i1 [[CMP20]], label [[IF_THEN22:%.*]], label [[COND_END:%.*]]
; CHECK:       if.then22:
; CHECK-NEXT:    [[INCDEC_PTR23:%.*]] = getelementptr inbounds i8, i8* [[FMT_ADDR_0_PN]], i32 2
; CHECK-NEXT:    [[DOTPR74:%.*]] = load i8, i8* [[INCDEC_PTR23]], align 1
; CHECK-NEXT:    [[TMP3:%.*]] = zext i8 [[DOTPR74]] to i32
; CHECK-NEXT:    [[TMP4:%.*]] = sub i32 [[TMP3]], 48
; CHECK-NEXT:    [[TMP5:%.*]] = icmp ult i32 [[TMP4]], 10
; CHECK-NEXT:    br i1 [[TMP5]], label [[WHILE_COND24:%.*]], label [[COND_END]]
; CHECK:       while.cond24:
; CHECK-NEXT:    br label [[WHILE_COND24]]
; CHECK:       cond.end:
; CHECK-NEXT:    [[FMT_ADDR_3]] = phi i8* [ [[FMT_ADDR_1]], [[WHILE_END18_SPLIT]] ], [ [[INCDEC_PTR23]], [[IF_THEN22]] ]
; CHECK-NEXT:    [[AND39:%.*]] = and i32 [[FLAGS_0]], 2048
; CHECK-NEXT:    [[TOBOOL40:%.*]] = icmp eq i32 [[AND39]], 0
; CHECK-NEXT:    br i1 [[TOBOOL40]], label [[WHILE_COND_OUTER_BACKEDGE]], label [[IF_THEN43:%.*]]
; CHECK:       while.cond.outer.backedge:
; CHECK-NEXT:    br label [[WHILE_COND_OUTER]]
; CHECK:       if.then43:
; CHECK-NEXT:    tail call void [[WRITE:%.*]](i32 43, i8* [[OUT:%.*]])
; CHECK-NEXT:    br label [[WHILE_COND_OUTER_BACKEDGE]]
; CHECK:       while.end48:
; CHECK-NEXT:    ret i32 undef
;
entry:
  br label %while.cond.outer

while.cond.outer:
  %fmt.addr.0.ph = phi i8* [ %fmt, %entry ], [ %fmt.addr.3, %while.cond.outer.backedge ]
  %0 = load i8, i8* %fmt.addr.0.ph, align 1
  br label %while.cond

while.cond:
  switch i8 %0, label %while.cond [
  i8 0, label %while.end48
  i8 37, label %while.cond2
  ]

while.cond2:
  %flags.0 = phi i32 [ %or, %while.cond2 ], [ 0, %while.cond ]
  %fmt.addr.0.pn = phi i8* [ %fmt.addr.1, %while.cond2 ], [ %fmt.addr.0.ph, %while.cond ]
  %fmt.addr.1 = getelementptr inbounds i8, i8* %fmt.addr.0.pn, i32 1
  %1 = load i8, i8* %fmt.addr.1, align 1
  %sub = add i8 %1, -32
  %conv6 = zext i8 %sub to i32
  %shl = shl i32 1, %conv6
  %and = and i32 %shl, 75785
  %tobool7 = icmp eq i32 %and, 0
  %or = or i32 %shl, %flags.0
  br i1 %tobool7, label %while.cond10.preheader, label %while.cond2

while.cond10.preheader:
  %.off = add i8 %1, -48
  %2 = icmp ult i8 %.off, 10
  br i1 %2, label %while.cond10, label %while.end18.split

while.cond10:
  br label %while.cond10

while.end18.split:
  %cmp20 = icmp eq i8 %1, 46
  br i1 %cmp20, label %if.then22, label %cond.end

if.then22:
  %incdec.ptr23 = getelementptr inbounds i8, i8* %fmt.addr.0.pn, i32 2
  %.pr74 = load i8, i8* %incdec.ptr23, align 1
  %.pr74.off = add i8 %.pr74, -48
  %3 = icmp ult i8 %.pr74.off, 10
  br i1 %3, label %while.cond24, label %cond.end

while.cond24:
  br label %while.cond24

cond.end:
  %fmt.addr.3 = phi i8* [ %fmt.addr.1, %while.end18.split ], [ %incdec.ptr23, %if.then22 ]
  %and39 = and i32 %flags.0, 2048
  %tobool40 = icmp eq i32 %and39, 0
  br i1 %tobool40, label %while.cond.outer.backedge, label %if.then43

while.cond.outer.backedge:
  br label %while.cond.outer

if.then43:
  tail call void %write(i32 43, i8* %out) #1
  br label %while.cond.outer.backedge

while.end48:
  ret i32 undef
}
